package com.ns.dcjh.ui.activity;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.luck.picture.lib.permissions.PermissionConfig.READ_EXTERNAL_STORAGE;
import static com.luck.picture.lib.permissions.PermissionConfig.READ_MEDIA_IMAGES;
import static com.luck.picture.lib.permissions.PermissionConfig.READ_MEDIA_VIDEO;
import static com.luck.picture.lib.permissions.PermissionConfig.READ_MEDIA_VISUAL_USER_SELECTED;

import android.Manifest;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.webkit.ConsoleMessage;
import android.webkit.CookieManager;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.hht.interface_.OfflineInterface;
import com.hht.webpackagekit.core.Constants;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.kongzue.dialog.v3.CustomDialog;
import com.liulishuo.filedownloader.FileDownloader;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.core.BasePopupView;
import com.lxj.xpopup.interfaces.SimpleCallback;
import com.lzf.easyfloat.EasyFloat;
import com.lzf.easyfloat.enums.ShowPattern;
import com.lzf.easyfloat.interfaces.OnPermissionResult;
import com.lzf.easyfloat.permission.PermissionUtils;
import com.lzf.easyfloat.utils.DisplayUtils;
import com.ns.dcjh.MyApplication;
import com.ns.dcjh.R;
import com.ns.dcjh.base.BaseActivity;
import com.ns.dcjh.bean.FloatWindow;
import com.ns.dcjh.bean.MessageEvent;
import com.ns.dcjh.constant.Constant;
import com.ns.dcjh.enums.TextColorEnum;
import com.ns.dcjh.listener.JSInterfaceHolderListener;
import com.ns.dcjh.listener.MyBDAbstractLocationListener;
import com.ns.dcjh.service.LocationService;
import com.ns.dcjh.ui.popup.FloatWindowPopup;
import com.ns.dcjh.ui.popup.OnFullScreenPopupChangeListener;
import com.ns.dcjh.ui.widget.MyScrollLinearLayout;
import com.ns.dcjh.ui.widget.OnScrollCompleteListener;
import com.ns.dcjh.utils.BlockUtils;
import com.ns.dcjh.utils.CrashHandler;
import com.ns.dcjh.utils.ExtraUtils;
import com.ns.dcjh.utils.FileUtils;
import com.ns.dcjh.utils.IntentUtils;
import com.ns.dcjh.utils.SharedPreferencesUtils;
import com.ns.dcjh.utils.SoftKeyboardFixerForFullscreen;
import com.ns.dcjh.utils.StatusBarUtils;
import com.ns.dcjh.utils.ToastUtils;
import com.ns.dcjh.utils.VibratorUtil;
import com.ns.dcjh.utils.WebviewPickerUtils;
import com.ns.dcjh.utils.upyun.UpYunCompleteListener;
import com.ns.dcjh.utils.upyun.UpYunEntity;
import com.ns.dcjh.utils.upyun.UpYunUtil;
import com.ns.dcjh.vo.AppRespVo;
import com.orhanobut.logger.Logger;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.yxing.ScanCodeConfig;

import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.BindView;
import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;


@SuppressLint("NonConstantResourceId")
public class WebviewX5Activity extends BaseActivity {
    @BindView(R.id.webview_container)
    WebView webView;
    @BindView(R.id.layout_loading)
    RelativeLayout layoutLoading;
    @BindView(R.id.layout_error)
    RelativeLayout layoutError;
    @BindView(R.id.btn_reload)
    TextView btnReload;

    //退出APP时间控制
    private Long mExitTime = 0L;
    //是否是首页地址
    private Boolean isHome = true;
    private JSInterfaceHolderListener jsListener;
    //定位服务
    private LocationService locationService;

    SharedPreferencesUtils sp;


    private String content;
    private int screenWidth;
    private int screenHeight;
    private FloatWindowPopup settingPopup;
    private int cutDownTime = 2; //默认倒计时时间
    private float textSize = 18f;
    private int textColorType = 1011; //字体颜色类型
    private boolean isTextMirror = false; //是否镜像
    private final int speedFactor = 20;
    //    private float speed = 2 / (4 + 0.4f * speedFactor); //默认速度2
    private float speed = 0.6f / speedFactor; //默认速度2
    private GestureDetector detector = null;
    private FloatWindow floatWindow = new FloatWindow();
    private VibratorUtil vibratorUtil;
    private final int loadCountDownTime = 5;
    private CountDownTimer loadCountDown;
    private boolean reloadFlag = false;

    private View mCustomView;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    private int mOriginalSystemUiVisibility;


    @Override
    protected int getLayoutId() {
        return R.layout.activity_webview_x5;
    }

    @Override
    protected void initData() {
        ((MyApplication) getApplication()).initDouYin();
        FileDownloader.setup(this);
        sp = SharedPreferencesUtils.getInstance(mContext);
        vibratorUtil = new VibratorUtil(this);
        getPackageIndex(Constants.BASE_PACKAGE_INDEX);
        initFloatWindow();
    }


    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("TAG", "onNewIntent");
        if (intent != null && intent.getExtras() != null) {
            String code = intent.getExtras().getString("type");

            if (jsListener == null) return;
            jsListener.sendNotificationResp(code);
        }
    }

    @Override
    protected void initView() {

        CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setAllowFileAccess(true);
        webView.getSettings().setAllowContentAccess(true);

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView webView, int i) {
                super.onProgressChanged(webView, i);
                if (i >= 100) {
                    //注入JS ，测试wap
                    webView.loadUrl("javascript:(function() { " +
                            "document.getElementById('app').style.height='100%';" +
                            "document.getElementById('app').style.width='100%'; " +
                            "document.getElementById('app').style.position='relative'; " +
                            "})()");
                }
            }

            @Override
            public void onShowCustomView(View view, CustomViewCallback callback) {
                // 处理全屏显示逻辑
                super.onShowCustomView(view, callback);
                // if a view already exists then immediately terminate the new one
                if (mCustomView != null) {
                    onHideCustomView();
                    return;
                }

                // 1. Stash the current state
                mCustomView = view;
                mCustomView.setBackgroundColor(Color.WHITE);
                mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();

                // 2. Stash the custom view callback
                mCustomViewCallback = callback;

                // 3. Add the custom view to the view hierarchy
                FrameLayout decor = (FrameLayout) getWindow().getDecorView();
                decor.addView(mCustomView, new FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));

                // 4. Change the state of the window
                getWindow().getDecorView().setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                                View.SYSTEM_UI_FLAG_FULLSCREEN |
                                View.SYSTEM_UI_FLAG_IMMERSIVE);
            }

            @Override
            public void onHideCustomView() {
                // 处理退出全屏逻辑
                super.onHideCustomView();
                // 1. Remove the custom view
                FrameLayout decor = (FrameLayout) getWindow().getDecorView();
                decor.removeView(mCustomView);
                mCustomView = null;

                // 2. Restore the state to it's original form
                getWindow().getDecorView().setSystemUiVisibility(mOriginalSystemUiVisibility);

                // 3. Call the custom view callback
                mCustomViewCallback.onCustomViewHidden();
                mCustomViewCallback = null;
            }

            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
                try {
                    String[] acceptTypes = fileChooserParams.getAcceptTypes();
//                    ToastUtils.info(mContext, "acceptTypes is " + acceptTypes[0]);
                    if (StringUtils.equals(acceptTypes[0], "image/*")) {
                        //选择图片
                        checkImageEnable(new AllowImageTodo() {
                            @Override
                            public void toDo() {
                                WebviewPickerUtils pickerUtils = new WebviewPickerUtils(mContext, valueCallback);
                                pickerUtils.openImagePicker(WebviewX5Activity.this, 20);
                            }
                        });
                    } else if (StringUtils.equals(acceptTypes[0], "video/*")) {
                        checkImageEnable(new AllowImageTodo() {
                            @Override
                            public void toDo() {
                                WebviewPickerUtils pickerUtils = new WebviewPickerUtils(mContext, valueCallback);
                                pickerUtils.openVideoPicker(WebviewX5Activity.this);
                            }
                        });
                    } else {
                        valueCallback.onReceiveValue(null);
                    }
                } catch (Exception e) {
//                    ToastUtils.info(mContext, "onShowFileChooser is out of exception , e.message = " + e.getMessage());
                    e.printStackTrace();
                    valueCallback.onReceiveValue(null);
                    return super.onShowFileChooser(webView, valueCallback, fileChooserParams);
                }

                return true;
            }

            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                //Logger.d(consoleMessage.message());
                return super.onConsoleMessage(consoleMessage);
            }
        });

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedError(WebView webView, int i, String s, String s1) {
                super.onReceivedError(webView, i, s, s1);
                Log.e("receivedError", String.format("WebView onReceivedError: %s %s", s, s1));
                if (!reloadFlag) {
                    webView.reload();
                    reloadFlag = true;
                } else {
                    layoutLoading.setVisibility(View.GONE);
                    layoutError.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) {
                return super.shouldInterceptRequest(webView, webResourceRequest);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String s) {
                Log.w("OverrideUrlLoading", s);
                if (StringUtils.startsWithIgnoreCase(s, "weixin://")) {
                    try {
                        Intent intent = new Intent(Intent.ACTION_MAIN);
                        intent.addCategory(Intent.CATEGORY_LAUNCHER);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.setComponent(new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"));
                        startActivity(intent);
                    } catch (Exception e) {
                        ToastUtils.info(mContext, "检测到您的手机没有安装微信，请安装后使用该功能");
                    }
                    return true;
                } else if (StringUtils.startsWith(s, "tel:")) {
                    String tel = s.replaceAll("(?i)tel:", "");
                    Log.i("call", "To call " + tel);
                    callPhone(tel);
                    return true;
                } else if (StringUtils.startsWithIgnoreCase(s, "snssdk1128://")) {
                    try {
                        Uri uri = Uri.parse(s);
                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                        intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
                        startActivity(intent);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return true;
                } else if (StringUtils.startsWith(s, "http://www.lefangsj.com/") ||
                        StringUtils.startsWith(s, "https://www.dichanw.com/wap/") ||
                        StringUtils.startsWith(s, "http://192.168")) {
                    return false;
                }
                return true;
            }

            private android.webkit.WebResourceResponse getWebResourceResponse(String url) {
                try {
                    return com.hht.webpackagekit.PackageManager.getInstance().getResource(url);
                } catch (Exception e) {
                    Log.e("Error", e.toString());
                    e.printStackTrace();
                }
                return null;
            }

            @SuppressLint("SetJavaScriptEnabled")
            @Override
            public void onPageFinished(WebView webView, String url) {
                super.onPageFinished(webView, url);
                webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); // 不加载缓存内容
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    WebView.setWebContentsDebuggingEnabled(true);
                }
                Logger.d(String.format("WebView onPageFinished: %s", url));
                CookieManager cookieManager = CookieManager.getInstance();
                final String cookies = cookieManager.getCookie(url);
                Logger.d("cookies.get==>" + cookies);
                if (cookies != null && !cookies.isEmpty()) {
                    sp.setObject("cookies", cookies);
                }
            }
        });

        webView.loadUrl(Constant.HOME_URL);


        if (sp.contain("cookies")) {
            CookieManager cookieManager = CookieManager.getInstance();
            String cookies = (String) sp.objectForKey("cookies", "");
            if (cookies.contains(";")) {
                String[] cs = cookies.split(";");
                for (String cookie : cs) {
                    cookieManager.setCookie(Constant.HOME_URL, cookie);
                }
            } else {
                cookieManager.setCookie(Constant.HOME_URL, cookies);
            }
        }


        //checkStorageCanAccess();
        mHandler.postDelayed(this::checkNotifyEnabled, 2000);
        mHandler.postDelayed(this::checkAlwaysFinish, 5000);

        initReloadCountDown();

        btnReload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.clearCache(true);
                webView.loadUrl(Constant.HOME_URL);
                initReloadCountDown();
            }
        });
        SoftKeyboardFixerForFullscreen.assistActivity(this);

        new Thread() {
            public void run() {
                try {
                    String crash = (String) SharedPreferencesUtils.getInstance(WebviewX5Activity.this)
                            .objectForKey(Constant.SP_KEY_PREVIOUS_CRASH, "");
                    if (!crash.isEmpty()) {
                        UpYunUtil upYunUtil = new UpYunUtil();
                        String packageName = getPackageName(); // 获取包名
                        String versionName = "unknown";
                        try {
                            PackageInfo pInfo = getPackageManager().getPackageInfo(packageName, 0);
                            versionName = pInfo.versionName; // 应用版本名
                        } catch (PackageManager.NameNotFoundException e) {
                            e.printStackTrace();
                        }
                        String path = "/crash/" + CrashHandler.formatDate(new Date(System.currentTimeMillis()), 22) + "/"
                                + versionName + "/"
                                + SharedPreferencesUtils.getInstance(WebviewX5Activity.this).objectForKey(Constant.SP_KEY_REGISTRATION_ID, "")
                                + "/crash.xcrash";
                        upYunUtil.formUpload(new File(crash), path, new UpYunCompleteListener() {
                            @Override
                            public void complete(@Nullable String url, @Nullable UpYunEntity entity) {
//                                Log.e("WebviewX5Activityaaa 253", "WebviewX5Activity 253");
                                SharedPreferencesUtils.getInstance(WebviewX5Activity.this).setObject(Constant.SP_KEY_PREVIOUS_CRASH, "");
                            }

                            @Override
                            public void fail(@Nullable String errorStr) {
//                                Log.e("WebviewX5Activityaaa 259", "WebviewX5Activity 259 fail: " + errorStr);
                            }

                            @Override
                            public void onProgress(int percent) {
//                                Log.e("WebviewX5Activityaaa 264", "WebviewX5Activity 264 percent: " + percent);
                            }
                        });
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void initReloadCountDown() {
        layoutLoading.setVisibility(View.VISIBLE);
        layoutError.setVisibility(View.GONE);
        loadCountDown = new CountDownTimer(loadCountDownTime * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {

            }

            @Override
            public void onFinish() { //倒计时结束
                //todo 把遮罩层去除
                layoutLoading.setVisibility(View.GONE);
                layoutError.setVisibility(View.VISIBLE);
                if (loadCountDown != null) {
                    loadCountDown.cancel();
                    loadCountDown = null;
                }
            }
        };

        loadCountDown.start();
    }

    @Override
    protected void initListener() {
        jsListener = new JSInterfaceHolderListener(mContext, webView);
        webView.addJavascriptInterface(jsListener, Constant.JS_INTERFACE_NAME);
        Log.e("TAG", "initListener");
    }

    @Override
    protected void dataRequest() {

    }

    @Override
    protected void onPause() {
        super.onPause();

        if (webView != null) {
            webView.onPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (webView != null) {
            webView.onResume();
        }
        deleteWxShareImages();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (webView != null) {
            webView.destroy();
        }
        if (locationService != null && locationService.isStart()) {
            locationService.stop();
        }
        if (vibratorUtil != null) {
            vibratorUtil.cancel();
        }

        if (loadCountDown != null) {
            loadCountDown.cancel();
            loadCountDown = null;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

            if (isHome) {
                exitApp();
            } else {
                webView.goBack();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageEvent messageEvent) {
        super.onMessageEvent(messageEvent);
        Integer messageId = messageEvent.getMessageId();
        JSONObject extras = messageEvent.getExtras();
        Logger.d(messageId);
        if (messageId.equals(Constant.MSG_EVENT_URL_IS_HOME)) {
            //是否首页
            isHome = extras.getBooleanValue("isHome");
        } else if (messageId.equals(Constant.MSG_EVENT_COMMAND_SENDMESSAGE_TO_WX)) {
            //分享微信图片返回
            if (jsListener == null) return;
            if (jsListener.umShareListener == null) return;
            if (jsListener.umShareListener.getOnSuccess() == null) return;

            jsListener.umShareListener.getOnSuccess().callbackWithBoolean(true, null);
        } else if (messageId.equals(Constant.MSG_EVENT_COMMAND_LAUNCH_WX_MINIPROGRAM)) {
            //分享小程序返回
            if (jsListener == null) return;
            jsListener.sendMpResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_GET_LOCATION)) {
            //获取定位
            getLocation(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_APP_UPGRADE)) {
            //更新APP
            mHandler.postDelayed(() -> startUpgrade(extras), 2000);
        } else if (messageId.equals(Constant.MSG_EVENT_SHARE_CONTENT_TO_TT_RESP)) {
            //分享抖音返回
            if (jsListener == null) return;
            jsListener.sendDyResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_RECEIVED_MSG)) {
            //接收到了消息
            if (jsListener == null) return;
            jsListener.sendMsgResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_PROMPT_EXIT)) {
            if (jsListener == null) return;
            AppRespVo vo = new AppRespVo();
            vo.setAction("prompt_finished");
            vo.setMessage("提词器关闭");
            vo.setStatus(true);
            jsListener.sendResponse(JSONObject.toJSONString(vo));
        } else if (messageId.equals(Constant.MSG_EVENT_FLOAT_SETTING)) {
            if (jsListener == null) return;
            if (extras.get("data") instanceof JSONObject) {
                JSONObject jsData = (JSONObject) extras.get("data");
                JSONObject params = jsData.getJSONObject("params");
                content = params.getString("text");

                if (!settingPopup.isShow()) {
                    settingPopup.show();
                }
            }
        } else if (messageId.equals(Constant.MSG_EVENT_AUTH_DOUYIN_RESP)) {
            //授权抖音返回
            if (jsListener == null) return;
            jsListener.sendDyAuthResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_SHARE_KUAISHOU_RESP)) {
            //快手分享返回
            if (jsListener == null) return;
            jsListener.sendKSShareResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_SHARE_XIAOHONGSHU_RESP)) {
            //小红书分享返回
            if (jsListener == null) return;
            jsListener.sendXIAOHONGSHUShareResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_REQUEST_CAMERA_PERMS)) {
            if (jsListener == null) return;

            if (extras.get("block") instanceof BlockUtils && extras.get("data") instanceof JSONObject) {
                checkCameraEnable(((BlockUtils) extras.get("block")), extras.getJSONObject("data"));
            }
        } else if (messageId.equals(Constant.MSG_EVENT_REQUEST_SCAN_SUCCESS)) {
            if (jsListener == null) return;
            jsListener.sendScanCodeResp(extras);
        } else if (messageId.equals(Constant.MSG_EVENT_REQUEST_VIBRATOR)) {
            if (jsListener == null) return;
            if (extras.get("data") instanceof JSONObject) {
                JSONObject jsData = (JSONObject) extras.get("data");
                JSONObject params = jsData.getJSONObject("params");
                long duration = params.getLong("duration");
                AppRespVo vo = new AppRespVo();
                vo.setAction("vibrator");
                if (duration > 0) {
                    vibratorUtil.open(duration);
                    vo.setMessage("已震动");
                    vo.setStatus(true);
                } else {
                    vo.setMessage("持续时间为0");
                    vo.setStatus(false);
                }
                jsListener.sendResponse(JSONObject.toJSONString(vo));
            }
        } else if (messageId.equals(Constant.MSG_EVENT_REQUEST_BROWSER)) {
            if (jsListener == null) return;
            if (extras.get("data") instanceof JSONObject) {
                JSONObject jsData = (JSONObject) extras.get("data");
                JSONObject params = jsData.getJSONObject("params");
                String url = params.getString("url");

                AppRespVo vo = new AppRespVo();
                vo.setAction("goto_browser");
                vo.setUser_data(jsData.getJSONObject("user_data"));

                Uri uri = Uri.parse(url);
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.setData(uri);
                mContext.startActivity(intent);
                vo.setStatus(true);
                vo.setMessage("跳转成功");
                jsListener.sendResponse(JSONObject.toJSONString(vo));
//                }

            }
        } else if (messageId.equals(Constant.MSG_EVENT_CALL_PHONE)) {
            try {
                String mobile = extras.getString("mobile");
                callPhone(mobile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (messageId.equals(Constant.MSG_EVENT_LOADED_NOTIFY)) {
            if (loadCountDown != null) {
                loadCountDown.cancel();
                loadCountDown = null;
            }
            layoutLoading.setVisibility(View.GONE);
            layoutError.setVisibility(View.GONE);
        } else if (messageId.equals(Constant.MSG_OFFLINE_PACKAGE_DOWNLOAD)) {
            getPackageIndex(extras.getString("package_url"));
        } else if (messageId.equals(Constant.STATUS_UI_UPDATE)) {
            if (!extras.getString("statusBarStyleBackgoundColor").isEmpty()) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        StatusBarUtils.setStatusBarColor((Activity) mContext, Color.parseColor(extras.getString("statusBarStyleBackgoundColor")),
                                "dark".equals(extras.getString("statusBarStyleTextColor")));
                    }
                });
            } else {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        StatusBarUtils.setTranslucentStatus((Activity) mContext, "dark".equals(extras.getString("statusBarStyleTextColor")));
                    }
                });
            }
        }
    }

    private void getPackageIndex(final String url) {
        com.hht.webpackagekit.PackageManager.getInstance().setOfflineInterface(new OfflineInterface() {
            @Override
            public void success() {
                if (jsListener == null) return;
                jsListener.returnOfflineResult("success");
            }

            @Override
            public void failed() {
                if (jsListener == null) return;
                jsListener.returnOfflineResult("failed");
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(url).build();
                    try (Response response = client.newCall(request).execute()) {
                        String data = response.body().string();
                        com.hht.webpackagekit.PackageManager.getInstance().update(data);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //退出APP
    private void exitApp() {
        if (System.currentTimeMillis() - mExitTime <= 2000) {
            finish();
        } else {
            mExitTime = System.currentTimeMillis();
            ToastUtils.info(mContext, "再按一次退出程序");
        }
    }

    private interface permissionCallbackListener {
        void successDo();

        void failDo();
    }

    interface AllowImageTodo {
        void toDo();
    }

    private void checkImageEnable(AllowImageTodo allowImageTodo) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if ((ContextCompat.checkSelfPermission(this, READ_MEDIA_IMAGES) != PERMISSION_GRANTED
                    || ContextCompat.checkSelfPermission(this, READ_MEDIA_VIDEO) != PERMISSION_GRANTED)) {
                // Android 13及以上完整照片和视频访问权限
                new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                        .setTitle("音视频权限使用说明")
                        .setMessage("全房源系统需要访问相册进行图片与视频的选择，请打开相应功能")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                new RxPermissions(WebviewX5Activity.this).request(
                                        READ_MEDIA_IMAGES,
                                        READ_MEDIA_VIDEO
                                ).subscribe(new Observer<Boolean>() {
                                    @Override
                                    public void onSubscribe(@NonNull Disposable d) {

                                    }

                                    @Override
                                    public void onNext(@NonNull Boolean aBoolean) {
                                        if (aBoolean) {
                                            allowImageTodo.toDo();
                                        }
                                    }

                                    @Override
                                    public void onError(@NonNull Throwable e) {

                                    }

                                    @Override
                                    public void onComplete() {

                                    }
                                });
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.dismiss();
                            }
                        })
                        .show();
            } else {
                allowImageTodo.toDo();
            }
        } else if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
            // Android 12及以下完整本地读写访问权限
            // Android 13及以上完整照片和视频访问权限
            new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                    .setTitle("存储权限使用说明")
                    .setMessage("全房源系统需要访问相册进行图片与视频的选择，请打开相应功能")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            new RxPermissions(WebviewX5Activity.this).request(
                                    READ_EXTERNAL_STORAGE
                            ).subscribe(new Observer<Boolean>() {
                                @Override
                                public void onSubscribe(@NonNull Disposable d) {

                                }

                                @Override
                                public void onNext(@NonNull Boolean aBoolean) {
                                    if (aBoolean) {
                                        allowImageTodo.toDo();
                                    }
                                }

                                @Override
                                public void onError(@NonNull Throwable e) {

                                }

                                @Override
                                public void onComplete() {

                                }
                            });
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .show();
        } else {
            allowImageTodo.toDo();
        }
    }


    //检测是否可以打开摄像头
    private void checkCameraEnable(BlockUtils blockUtils, JSONObject data) {
        if (XXPermissions.isGranted(this, Permission.CAMERA)) {
            blockUtils.callback();
        } else {
            new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                    .setTitle("相机权限使用说明")
                    .setMessage("全房源系统需要访问相机来拍摄图片和视频。也可以使用「扫一扫」识别二维码。")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            new RxPermissions(WebviewX5Activity.this).request(
                                    Manifest.permission.CAMERA
                            ).subscribe(new Observer<Boolean>() {
                                @Override
                                public void onSubscribe(@NonNull Disposable d) {

                                }

                                @Override
                                public void onNext(@NonNull Boolean aBoolean) {
                                    if (jsListener == null) return;
                                    if (aBoolean) {
                                        blockUtils.callback();
                                    } else {
                                        AlertDialog mDialog = new AlertDialog.Builder(mContext)
                                                .setTitle(R.string.txt_dialog_title)
                                                .setMessage("需要访问您的存储卡，才能使用此功能，是否立即设置？\n步骤如下：\n应用程序设置 -> 权限 -> 相机 -> 允许")
                                                .setNegativeButton(R.string.txt_cancel, (dialog, which) -> {
                                                    dialog.dismiss();
                                                    if (jsListener != null)
                                                        jsListener.sendCameraFailResp(data);
                                                })
                                                .setPositiveButton(R.string.txt_setting, (dialog, which) -> {
                                                    IntentUtils.openAppSettings(mContext);
                                                    if (jsListener != null)
                                                        jsListener.sendCameraFailResp(data);
                                                })
                                                .create();
                                        mDialog.show();
                                    }
                                }

                                @Override
                                public void onError(@NonNull Throwable e) {

                                }

                                @Override
                                public void onComplete() {

                                }
                            });
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .show();
        }

    }


    //检测是否开启了通知
    private void checkNotifyEnabled() {
        if (ExtraUtils.isNotificationEnabled(mContext)) return;
        if (sp.contain("notifyDialog")) return;

        CustomDialog.build(mContext, R.layout.layout_dialog_notify, (dialog, v) -> {
            ImageView imgDialogClose = v.findViewById(R.id.img_dialog_close);
            Button btnDialogOpen = v.findViewById(R.id.btn_dialog_open);

            imgDialogClose.setOnClickListener(v1 -> dialog.doDismiss());
            btnDialogOpen.setOnClickListener(v12 -> {
                dialog.doDismiss();
                IntentUtils.openNotifySettings(mContext);
            });

        }).setOnShowListener(dialog -> {
            sp.setObject("notifyDialog", true);
        }).setCancelable(false).show();
    }

    //获取定位
    private void getLocation(JSONObject userData) {
        if (XXPermissions.isGranted(this, Permission.ACCESS_COARSE_LOCATION, Permission.ACCESS_FINE_LOCATION)) {
            if (locationService == null)
                locationService = new LocationService(MyApplication.getInstance().getApplicationContext());
            MyBDAbstractLocationListener listener = new MyBDAbstractLocationListener();
            listener.setOnReceive(new BlockUtils() {
                @Override
                public void callbackWithJSONObject(JSONObject data) {
                    jsListener.sendLocationSuccessResp(data, userData);
                    locationService.stop();
                    locationService.unregisterListener(listener);
                }
            });
            locationService.registerListener(listener);
            locationService.start();
        } else {
            new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                    .setTitle("位置权限使用说明")
                    .setMessage("定位当前区域以方便用户选择当前区域")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            new RxPermissions(WebviewX5Activity.this).request(
                                    Manifest.permission.ACCESS_COARSE_LOCATION,
                                    Manifest.permission.ACCESS_FINE_LOCATION
                            ).subscribe(new Observer<Boolean>() {
                                @Override
                                public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {

                                }

                                @Override
                                public void onNext(@io.reactivex.annotations.NonNull Boolean aBoolean) {
                                    if (jsListener == null) return;

                                    if (aBoolean) {
                                        if (locationService == null)
                                            locationService = new LocationService(MyApplication.getInstance().getApplicationContext());
                                        MyBDAbstractLocationListener listener = new MyBDAbstractLocationListener();
                                        listener.setOnReceive(new BlockUtils() {
                                            @Override
                                            public void callbackWithJSONObject(JSONObject data) {
                                                jsListener.sendLocationSuccessResp(data, userData);
                                                locationService.stop();
                                                locationService.unregisterListener(listener);
                                            }
                                        });
                                        locationService.registerListener(listener);
                                        locationService.start();
                                    } else {
                                        jsListener.sendLocationFailResp(userData);
                                    }
                                }

                                @Override
                                public void onError(@io.reactivex.annotations.NonNull Throwable e) {

                                }

                                @Override
                                public void onComplete() {

                                }
                            });
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();

                        }
                    })
                    .show();
        }

    }

    /**
     * 拨打电话新权限申请
     */
    private void callPhone(String mobile) {
        if (XXPermissions.isGranted(this, Permission.CALL_PHONE)) {
            IntentUtils.openCall(mContext, mobile);
        } else {
            new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                    .setTitle("电话权限使用说明")
                    .setMessage("全房源系统需要拨打电话权限，以便跟用户进行电话沟通")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            XXPermissions.with(WebviewX5Activity.this)
                                    // 申请单个权限
                                    .permission(Permission.CALL_PHONE)
                                    .request(new OnPermissionCallback() {

                                        @Override
                                        public void onGranted(List<String> permissions, boolean all) {
                                            IntentUtils.openCall(mContext, mobile);
                                        }

                                        @Override
                                        public void onDenied(List<String> permissions, boolean never) {
                                            if (never) {
                                                // 如果是被永久拒绝就跳转到应用权限系统设置页面
                                                new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                                                        .setTitle("电话权限使用说明")
                                                        .setMessage("您已禁止了电话授权，请打开系统设置重新开启电话授权")
                                                        .setPositiveButton("去授权", new DialogInterface.OnClickListener() {
                                                            @Override
                                                            public void onClick(DialogInterface dialogInterface, int i) {
                                                                XXPermissions.startPermissionActivity(mContext, permissions);
                                                            }
                                                        })
                                                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                                            @Override
                                                            public void onClick(DialogInterface dialogInterface, int i) {
                                                                dialogInterface.dismiss();
                                                            }
                                                        })
                                                        .show();
                                            } else {
                                                ToastUtils.info(mContext, "您已禁止了电话授权，请重试申请");
                                            }
                                        }
                                    });
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .show();
        }
    }

    private void requestFloatPermission() {
        PermissionUtils.requestPermission(this, new OnPermissionResult() {
            @Override
            public void permissionResult(boolean isOpen) {
                if (isOpen) {
                    showFloat();
                } else {
                    ToastUtils.info(WebviewX5Activity.this, "悬浮窗权限授权失败，请再次申请");
                }
            }
        });
    }

    //自动删除微信分享的照片
    private void deleteWxShareImages() {
        try {
            ArrayList<String> wxShareImages = MyApplication.getInstance().getWxShareImageList();
            if (wxShareImages != null && !wxShareImages.isEmpty()) {
                for (String filePath : wxShareImages) {
                    File file = new File(filePath);
                    file.delete();
                }
            }
            mApp.clearWxShareImageList();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && data != null) {
            if (requestCode == ScanCodeConfig.QUESTCODE) {//接收扫码结果
                Bundle extras = data.getExtras();
                if (extras != null) {
                    int codeType = extras.getInt(ScanCodeConfig.CODE_TYPE);
                    String code = extras.getString(ScanCodeConfig.CODE_KEY);
                    Log.e("Tag", String.format(
                            "扫码结果：\n" +
                                    "码类型: %s  \n" +
                                    "码值  : %s", codeType == 0 ? "一维码" : "二维码", code));
                    if (code == null || code.isEmpty()) {
                        ToastUtils.info(this, "未识别该二维码，请重试");
                    } else {
                        MessageEvent msgEvent = new MessageEvent(Constant.MSG_EVENT_REQUEST_SCAN_SUCCESS);
                        JSONObject jsonData = new JSONObject();
                        jsonData.put("code", code);
                        msgEvent.setExtras(jsonData);
                        EventBus.getDefault().post(msgEvent);
                    }
                }
            }
        }
    }

    private void initFloatWindow() {
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;
        getDefaultSettingValue();
        initPopup();
    }

    private void getDefaultSettingValue() {
        String jsonStr;
        if (sp.contain("floatSetting")) {
            jsonStr = (String) sp.objectForKey("floatSetting", "");
        } else {
            jsonStr = FileUtils.getAssetsJson("float_window.json", this);
        }
        floatWindow = new Gson().fromJson(jsonStr, FloatWindow.class);
        cutDownTime = floatWindow.cutDownTime;
        textSize = floatWindow.textSize;
        textColorType = floatWindow.textColorType;
        speed = floatWindow.speed / speedFactor;
        isTextMirror = floatWindow.isTextMirror == 1;
    }

    private void initPopup() {
        settingPopup = (FloatWindowPopup) new XPopup.Builder(this)
                .hasShadowBg(true)
                .setPopupCallback(new SimpleCallback() {
                    @Override
                    public void onShow(BasePopupView popupView) {
                        super.onShow(popupView);

                    }

                    @Override
                    public void onDismiss(BasePopupView popupView) {
                        super.onDismiss(popupView);
                    }
                })
                .asCustom(new FloatWindowPopup(this, floatWindow));


        settingPopup.setOnFullScreenPopupChangeListener(new OnFullScreenPopupChangeListener() {
            @Override
            public void onChangeBackgroundColor(int colorType) {
            }

            @Override
            public void onChangeTextColor(int colorType) {
                textColorType = colorType;
                floatWindow.textColorType = colorType;
            }

            @Override
            public void onChangeTextSize(int size) {
                textSize = size;
                floatWindow.textSize = size;
            }

            @Override
            public void onChangeSwitchReverseText(boolean isOn) {
                isTextMirror = isOn;
                floatWindow.isTextMirror = isTextMirror ? 1 : 0;
            }

            @Override
            public void onChangeCutDownTime(int time) {
                cutDownTime = time;
                floatWindow.cutDownTime = time;
            }

            @Override
            public void onChangeSpeed(float speedValue) {
                speed = speedValue / speedFactor;
                floatWindow.speed = speedValue;
            }

            @Override
            public void onCompleteClick() {
                settingPopup.dismiss();
                saveSettings();
                if (PermissionUtils.checkPermission(WebviewX5Activity.this)) {
                    showFloat();
                } else {
                    new androidx.appcompat.app.AlertDialog.Builder(WebviewX5Activity.this)
                            .setTitle("悬浮框权限使用说明")
                            .setMessage("全房源系统需要开启悬浮窗权限，以便进行展示提词器功能")
                            .setPositiveButton("去开启", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    requestFloatPermission();
                                }
                            })
                            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    dialogInterface.dismiss();
                                }
                            })
                            .show();
                }
            }

            @Override
            public void onRecover() {
                floatWindow = null;
                sp.removeObjectForKey("floatSetting");
                floatWindow = new Gson().fromJson(FileUtils.getAssetsJson("float_window.json", WebviewX5Activity.this), FloatWindow.class);
                cutDownTime = floatWindow.cutDownTime;
                textSize = floatWindow.textSize;
                textColorType = floatWindow.textColorType;
                speed = floatWindow.speed / speedFactor;
                isTextMirror = floatWindow.isTextMirror == 1;
            }
        });
    }


    private void saveSettings() {
        String jsonStr = new Gson().toJson(floatWindow);
        sp.setObject("floatSetting", jsonStr);
    }

    private boolean isLandscape = false;
    private int contentTextHeight = 0;
    private final int startOriginY = 450;
    private final Handler handler = new Handler();
    //是否滚动结束
    private boolean isScrollFinish = false;
    //是否滚动暂停
    private boolean isScrollPause = false;
    //Y轴手势移动的距离
    private int gestureHeight = 0;
    private int gestureType = -1; // 0代表单击 1代表滑动
    private CountDownTimer countDownTimer;


    @SuppressLint("ClickableViewAccessibility")
    private void showFloat() {
        EasyFloat.with(this.getApplication())
                // 设置浮窗xml布局文件
                .setLayout(R.layout.layout_float_window, view -> {

                    MyScrollLinearLayout scrollView = view.findViewById(R.id.floatWindowContentRoot);
                    TextView displayContent = view.findViewById(R.id.displayContent);
                    ImageView imgScrollStatus = view.findViewById(R.id.floatWindowScrollStatusImage);
                    ImageView imgScrollRefresh = view.findViewById(R.id.floatWindowScrollRefreshImage);
                    TextView floatWindowFinishScrollTxt = view.findViewById(R.id.floatWindowFinishScrollTxt);
                    RelativeLayout floatWindowCutDownRoot = view.findViewById(R.id.floatWindowCutDownRoot);
                    TextView displayCutDownText = view.findViewById(R.id.displayCutDownText);

                    FrameLayout rootView = view.findViewById(R.id.floatWindowRootView);
                    ViewGroup.LayoutParams lp = rootView.getLayoutParams();
                    lp.width = screenWidth;
                    lp.height = screenWidth;
                    rootView.setLayoutParams(lp);

                    LinearLayout floatView = view.findViewById(R.id.floatWindowLl);
                    FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) floatView.getLayoutParams();
                    flp.width = screenWidth;
                    flp.height = screenWidth - 350;
                    flp.gravity = Gravity.CENTER;
                    floatView.setLayoutParams(flp);

                    ImageView btnRotation = view.findViewById(R.id.floatWindowBtnRotation);
                    ImageView btnClose = view.findViewById(R.id.floatWindowBtnClose);


                    detector = new GestureDetector(WebviewX5Activity.this, new GestureDetector.SimpleOnGestureListener() {

                        private int y;

                        @Override
                        public boolean onDown(MotionEvent e) {
                            Log.e("TAG", "触碰了");
                            //记录手指触碰初始位置
                            y = (int) e.getY();
                            return true;
                        }

                        @Override
                        public boolean onSingleTapUp(MotionEvent e) {
                            gestureType = 0;
                            startContentMove(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt);
                            return super.onSingleTapUp(e);
                        }

                        @Override
                        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                            gestureType = 1;
                            int startY = (int) e1.getY();
                            int endY = (int) e2.getY();
                            scrollView.stopScroll();
                            int offsetY = endY - y;
                            scrollView.scrollBy(0, -offsetY);
                            y = endY;
                            gestureHeight = startY - endY;
                            if (gestureHeight < 0 && gestureHeight < ((int) (0.4 * (screenWidth - 350)) + scrollView.getCurrY() + 100) * -1) { //向下滑出屏幕
                                gestureType = -1;

                                isScrollFinish = true;
                                isScrollPause = false;
                                floatWindowFinishScrollTxt.bringToFront();
                                floatWindowFinishScrollTxt.setVisibility(View.VISIBLE);

                                imgScrollStatus.setBackgroundResource(R.mipmap.ic_play_float);
                            }
                            return true;
                        }
                    });


                    btnRotation.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ObjectAnimator objectAnimator;
                            if (isLandscape) {
                                objectAnimator = ObjectAnimator.ofFloat(rootView, "rotation", 90f, 0f).setDuration(300);
                            } else {
                                objectAnimator = ObjectAnimator.ofFloat(rootView, "rotation", 0f, 90f).setDuration(300);
                            }
                            objectAnimator.start();
                            isLandscape = !isLandscape;
                        }
                    });


                    btnClose.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            EasyFloat.dismiss("float");
                            isScrollFinish = false;
                            isScrollPause = false;

                            if (countDownTimer != null) {
                                countDownTimer.cancel();
                                countDownTimer = null;
                            }
                        }
                    });


                    scrollView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View view, MotionEvent motionEvent) {
                            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                                EasyFloat.dragEnable(false, "float");
                            }
                            if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

                            }
                            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                                EasyFloat.dragEnable(true, "float");
                                if (gestureType == 1) {
                                    if (!isScrollPause) {
                                        startScrollByStartY(scrollView, scrollView.getScrollY());
                                    }
                                }
                            }
                            if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
                                EasyFloat.dragEnable(true, "float");
                            }
                            return detector.onTouchEvent(motionEvent);
                        }
                    });

                    scrollView.setContentTopDistance((int) (0.6 * (screenWidth - 350)));

                    scrollView.setOnScrollCompleteListener(new OnScrollCompleteListener() {
                        @Override
                        public void onScrollComplete(int dy) {
                            if (dy >= (int) (0.6 * (screenWidth - 350)) + contentTextHeight + 200 && scrollView.getScrollY() > startOriginY) {
                                isScrollFinish = true;
                                isScrollPause = false;
                                floatWindowFinishScrollTxt.bringToFront();
                                floatWindowFinishScrollTxt.setVisibility(View.VISIBLE);
                                imgScrollStatus.setBackgroundResource(R.mipmap.ic_play_float);
                            }
                        }

                    });


                    displayContent.setText(content);
                    displayContent.setTextSize(textSize);
                    displayContent.setTextColor(getResources().getColor(TextColorEnum.getColorByType(textColorType)));
                    if (isTextMirror) {
                        displayContent.setScaleX(-1);
                    } else {
                        displayContent.setScaleX(1);
                    }


                    displayContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                        @Override
                        public void onGlobalLayout() {
                            if (displayContent != null) {
                                contentTextHeight = displayContent.getLayout().getHeight()  //  文字的高度
                                        + displayContent.getPaddingTop()
                                        + displayContent.getPaddingBottom();
                                Log.e("TAG", "contentHeight=" + contentTextHeight);
                            }
                        }
                    });

                    scrollView.initScrollY(startOriginY);
                    startCountDownTime(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt, new CountTimeEnd() {
                        @Override
                        public void end() {
                            startScrollByStartY(scrollView, startOriginY);
                        }
                    });

                    imgScrollStatus.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            startContentMove(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt);
                        }
                    });

                    imgScrollRefresh.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            scrollView.initScrollY(startOriginY);
                            startCountDownTime(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt,
                                    new CountTimeEnd() {
                                        @Override
                                        public void end() {
                                            floatWindowFinishScrollTxt.setVisibility(View.GONE);
                                            startScrollByStartY(scrollView, startOriginY);
                                            isScrollFinish = false;
                                        }
                                    });
                        }
                    });

                    floatWindowFinishScrollTxt.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) { //重新播放
                            scrollView.initScrollY(startOriginY);
                            startCountDownTime(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt,
                                    new CountTimeEnd() {
                                        @Override
                                        public void end() {
                                            floatWindowFinishScrollTxt.setVisibility(View.GONE);
                                            startScrollByStartY(scrollView, startOriginY);
                                            isScrollFinish = false;
                                        }
                                    });
                        }
                    });

                })
                .setShowPattern(ShowPattern.ALL_TIME)
                .setImmersionStatusBar(true)
                .setDragEnable(true)
                .setTag("float")
                .setLocation(0, screenHeight / 2 - screenWidth / 2)
                // 设置浮窗的出入动画，可自定义，实现相应接口即可（策略模式），无需动画直接设置为null
                .setAnimator(null)
                // 设置系统浮窗的有效显示高度（不包含虚拟导航栏的高度），基本用不到，除非有虚拟导航栏适配问题
                .setDisplayHeight(DisplayUtils.INSTANCE::rejectedNavHeight)
                // 浮窗的一些状态回调，如：创建结果、显示、隐藏、销毁、touchEvent、拖拽过程、拖拽结束。
                .registerCallback(builder -> {
                    builder.createResult((aBoolean, s, view) -> {

                        return null;
                    });

                    builder.dismiss(() -> {
                        MessageEvent msgEvent = new MessageEvent(Constant.MSG_EVENT_PROMPT_EXIT);
                        EventBus.getDefault().post(msgEvent);
                        return null;
                    });
                    builder.touchEvent((view, event) -> {

                        return null;
                    });


                    return null;
                })
                .show();

    }

    public void startScrollByStartY(MyScrollLinearLayout scrollView, int startY) {
        scrollView.setScrollY(startY);
        int dy = (int) (0.6 * (screenWidth - 350)) + contentTextHeight + 200 - startY;
        scrollView.startScroll(dy, startY, speed);
        isScrollPause = false;
    }

    interface CountTimeEnd {
        void end();
    }

    public void startContentMove(MyScrollLinearLayout scrollView, RelativeLayout
            floatWindowCutDownRoot,
                                 TextView displayCutDownText, ImageView imgScrollStatus, TextView
                                         floatWindowFinishScrollTxt) {
        if (isScrollFinish) {
            floatWindowFinishScrollTxt.setVisibility(View.GONE);

            startScrollByStartY(scrollView, startOriginY);
            imgScrollStatus.setBackgroundResource(R.mipmap.ic_puase_float);
            isScrollFinish = false;
        } else {
            if (isScrollPause) {
                startCountDownTime(scrollView, floatWindowCutDownRoot, displayCutDownText, imgScrollStatus, floatWindowFinishScrollTxt,
                        new CountTimeEnd() {
                            @Override
                            public void end() {
                                startScrollByStartY(scrollView, scrollView.getScrollY());
                            }
                        });
            } else {
                scrollView.stopScroll();
                imgScrollStatus.setBackgroundResource(R.mipmap.ic_play_float);
            }
            isScrollPause = !isScrollPause;
        }
    }

    public void startCountDownTime(MyScrollLinearLayout scrollView, RelativeLayout
            floatWindowCutDownRoot,
                                   TextView displayCutDownText, ImageView imgScrollStatus, TextView
                                           floatWindowFinishScrollTxt, CountTimeEnd countTimeEnd) {
        if (cutDownTime > 0) {
            scrollView.setVisibility(View.VISIBLE);
            scrollView.stopScroll();
            isScrollPause = false;
            floatWindowFinishScrollTxt.setVisibility(View.GONE);
            floatWindowCutDownRoot.setVisibility(View.VISIBLE);
            displayCutDownText.setText(String.valueOf(cutDownTime));
            countDownTimer = new CountDownTimer(cutDownTime * 1000, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    String value = String.valueOf((int) (millisUntilFinished / 1000));
                    displayCutDownText.setText(value);
                }

                @Override
                public void onFinish() { //倒计时结束
                    floatWindowCutDownRoot.setVisibility(View.GONE);
                    scrollView.setVisibility(View.VISIBLE);

                    countTimeEnd.end();
                    imgScrollStatus.setBackgroundResource(R.mipmap.ic_puase_float);
                    if (countDownTimer != null) {
                        countDownTimer.cancel();
                        countDownTimer = null;
                    }
                }
            };

            countDownTimer.start();

        } else {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startScrollByStartY(scrollView, startOriginY);
                    imgScrollStatus.setBackgroundResource(R.mipmap.ic_puase_float);
                }
            }, 300);
        }
    }
}